package top.codef.secure.config.delegates;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.web.csrf.CsrfLogoutHandler;
import org.springframework.security.web.csrf.CsrfTokenRepository;
import org.springframework.security.web.csrf.HttpSessionCsrfTokenRepository;

import top.codef.secure.config.interfaces.CerberusHttpSecurityConfig;
import top.codef.secure.properties.CerberusCsrfProperties;

@Configuration
@EnableConfigurationProperties(CerberusCsrfProperties.class)
@ConditionalOnProperty(name = "cerberus.secure.csrf.enabled", havingValue = "true", matchIfMissing = true)
@Order(1)
public class CerberusCsrfSecureConfig implements CerberusHttpSecurityConfig {

	@Autowired
	private CerberusCsrfProperties cerberusCsrfProperties;

	private final Log logger = LogFactory.getLog(CerberusCsrfSecureConfig.class);

	@Override
	public void secure(HttpSecurity httpSecurity) throws Exception {
		logger.debug("csrf设置");
		if (cerberusCsrfProperties.isEnabled()) {
			CsrfTokenRepository csrfTokenRepository = csrfTokenRepository();
			httpSecurity
					.csrf(x -> x
							.ignoringRequestMatchers(
									cerberusCsrfProperties.getIgnoringPathMatchers().toArray(new String[] {}))
							.csrfTokenRepository(csrfTokenRepository))
					.logout(x -> x.addLogoutHandler(new CsrfLogoutHandler(csrfTokenRepository)));
			;
		} else
			httpSecurity.csrf(x -> x.disable()).headers(x -> {
			});
	}

	@Bean
	public CsrfTokenRepository csrfTokenRepository() {
		HttpSessionCsrfTokenRepository httpSessionCsrfTokenRepository = new HttpSessionCsrfTokenRepository();
		httpSessionCsrfTokenRepository.setHeaderName(cerberusCsrfProperties.getCsrfHeaderName());
		httpSessionCsrfTokenRepository.setSessionAttributeName(cerberusCsrfProperties.getCsrfSessionAttrName());
		return httpSessionCsrfTokenRepository;
	}
}
